從左畫面將訊息推送到右邊畫面,嗯! 就這樣。
本示例從主畫面推送訊息,其他開啟本網的使用者無論畫面停留在哪個頁面,皆能接收到該訊息 Notificatin 。
當有資訊要從某頁傳送到另一個畫面,或者從後台將資訊推送給前端畫面時,即可使用Push推送。
Vaadin 使用 Atmosphere framework做為client-server 通訊框架,預設採用 WebSocket
連線,若 Browser或Server不支援的話,則改用 Browser 支援的通訊協定。
一般常見的訊息推播、優惠通知、購買通知、訊息公告皆可用Push/Broadcast。另外,亦可應用在協同編輯、非同步更新、狀態監控...等功能。
為避免 deadlock 建議使用Queue,透過單獨線程排隊發送,最簡單、安全的方式就是使用 java 的 Synchronized 鎖定。
class Broadcaster {
companion object{
var executor: Executor = Executors.newSingleThreadExecutor()
var listeners = LinkedList<Consumer<String>>()
@Synchronized
fun register(listener: Consumer<String>): Registration? {
listeners.add(listener)
return Registration {
synchronized(Broadcaster::class.java) { listeners.remove(listener) }
}
}
@Synchronized
fun broadcast(message: String) {
for (listener in listeners) {
executor.execute { listener.accept(message) }
}
}
}
}
在本例中,由於所有的畫面都會設定 layout 為 MainLayout
( @Route("path", layout = MainLayout::class
),所以直接將接收寫在此layout上。
var broadcasterRegistration: Registration? = null
override fun onAttach(attachEvent: AttachEvent?) {
val ui = attachEvent!!.ui
broadcasterRegistration = Broadcaster.register{ newMessage->
ui.access{
Notification(newMessage, 3000).open()
}
}!!
super.onAttach(attachEvent)
}
override fun onDetach(detachEvent: DetachEvent?) {
broadcasterRegistration?.let { it.remove() }
broadcasterRegistration = null
super.onDetach(detachEvent)
}
class 上方加上 @Push
@Push
@AllowAll
@Viewport(Viewport.DEVICE_DIMENSIONS)
class MainLayout: KComposite(), RouterLayout, BeforeEnterObserver {
:
:
:
}
以下程式碼可寫在任何要發送訊息的頁面上,本例寫在主畫面 MainView.kt
val txtMessage = textField("message")
button("Send Broadcast"){
onLeftClick {
Broadcaster.broadcast(txtMessage.value)
}
}